package com.fengsh.nacos.components;

import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import org.slf4j.Logger;

/**
 * @标题 全局过滤器
 * @作者 fengsh998
 * @创建时间 2024/1/31
 * @功能描述
 */

@Component
public class GlobalCustomFilter implements GlobalFilter, Ordered {
    private static final Logger logger = LoggerFactory.getLogger(GlobalCustomFilter.class);
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        logger.info("前置过滤实现处.....");
        ServerHttpRequest request = exchange.getRequest();
        doPreRequestLog(request);
        ServerHttpResponse response = exchange.getResponse();
        doAfterResponse(response);
        return chain.filter(exchange).then(Mono.fromRunnable(
                () -> {
                    logger.info("后置过滤器处理处......");
                }
        ));
    }

    /**
     * 过滤器优先级，当有多个过滤器时就会按优先有顺序进行请求，请求和响应顺序遵循栈的方式。
     * @return
     */
    @Override
    public int getOrder() {
        return 2;
    }

    private void doPreRequestLog(ServerHttpRequest request) {
        String host = request.getRemoteAddress().getHostString();
        String scheme = request.getURI().getScheme();
        String method =request.getMethod().toString();
        String path = request.getPath().pathWithinApplication().value();
        String query_params = request.getQueryParams().toString(); //Get query params.
        String current_reqId = request.getId();

        HttpHeaders headers = request.getHeaders();

        String body = null;
        MediaType content_type = headers.getContentType();
        if (
                MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(content_type) ||
                        MediaType.APPLICATION_JSON.isCompatibleWith(content_type)
        ) {
            body = request.getBody().toString();
        }
        logger.info("=======================================Gateway_Request=============================");
        logger.info("RequestID:" + current_reqId);
        logger.info("Path:" + path);
        logger.info("Host:" + host);
        logger.info("Scheme:" + scheme);
        logger.info("Method:" + method);
        logger.info("Query params:" + query_params);
        logger.info("Body:" + body);
        logger.info("【headers】:");
        logger.info(headers.toString());


    }

    private void doAfterResponse(ServerHttpResponse response) {
        HttpHeaders response_headers = response.getHeaders();
        HttpStatusCode code = response.getStatusCode();
        DataBufferFactory bufferFactory = response.bufferFactory();
        logger.info("----- Response: ----");
        logger.info("Status Code:" + code.toString());
        logger.info("【Response Headers:】");
        logger.info(response_headers.toString());
        logger.info("========================================= request end =================================");
    }

}
